package com.google.code.jtasks.client.ui.commands;

import com.google.code.jtasks.client.exceptions.TerminateException;
import com.google.code.jtasks.client.services.TaskService;
import com.google.code.jtasks.client.ui.Command;
import com.google.code.jtasks.client.ui.ScreenHelper;
import com.google.code.jtasks.client.ui.TaskOutputter;
import com.google.code.jtasks.common.data.Task;
import com.google.common.base.Optional;
import com.google.inject.Inject;

import java.util.List;

/**
 * Команда поиска задач по подстроке в их именах.
 */
public class FindTasksCommand implements Command {
    private final ScreenHelper helper;
    private final TaskOutputter outputter;
    private final TaskService taskService;

    @Inject
    FindTasksCommand(ScreenHelper helper, TaskOutputter outputter, TaskService taskService) {
        this.helper = helper;
        this.outputter = outputter;
        this.taskService = taskService;
    }

    @Override
    public String name() {
        return "Find task";
    }

    @Override
    public String description() {
        return "Search for a task by a part of its name";
    }

    @Override
    public void execute() throws TerminateException {
        int y = 2;
        Optional<String> name = readName(y);
        if (!name.isPresent()) {
            return;
        }
        y += 3;

        List<Task> tasks = findTasks(y, name.get());
        y += 2;
        if (tasks.isEmpty()) {
            helper.drawString(5, y, "No tasks have been found.");
            y += 2;
        } else {
            helper.drawString(5, y, "Found these tasks:");
            y += 2;
            y = outputter.printTasks(y, tasks);
        }

        helper.waitForKey(y);
    }

    /**
     * Выполняет запрос к сервису на поиск задач, содержащих заданную строку в имени, выводя соответствующие
     * сообщения пользователю.
     *
     * @param y вертикальное смещение строки, на которой выводить сообщения
     * @param name подстрока в имени задачи
     * @return список найденный задач
     */
    private List<Task> findTasks(int y, String name) {
        String message = "Loading tasks...";
        helper.refresh();
        helper.drawString(5, y, message);

        List<Task> tasks = taskService.findTaskByName(name);

        helper.drawString(5 + message.length() + 1, y, "Done.");
        helper.refresh();
        return tasks;
    }

    /**
     * Считывает подстроку, которую следует искать в именах задач, вместе с сопутствующим выводом сообщения.
     *
     * @param y смещение по вертикали, на котором выводить сообщение
     * @return {@code Optional.of(значение)}, если было введение значение и был нажат Enter, {@code Optional.absent()},
     *         если был нажат Escape
     */
    private Optional<String> readName(int y) {
        helper.drawString(5, y, "Enter part of task name:");
        return helper.readStringWithOutputAt(5, y+1);
    }
}
